package at.moop.eneo.service;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import at.moop.eneo.EneoActivity;
import at.moop.eneo.PointSubmitter;
import at.moop.eneo.R;
import at.moop.eneo.model.Point;
import at.moop.eneo.util.Properties;

public class SubmitterService extends Service implements OnSharedPreferenceChangeListener {
	// Fields that change with every submission
	public double lat;
	public double lng;
	public String stmp;
	
	// Time of last captured submission (time of capture, not final submission!)
	public long last = 0;
	static final int DELAY = 2;
	
	// Time of last actual submission
	public long last_full_submission;
	public String last_response;
	public String last_full_submission_string;
	
	// Whether service is running or not
	private boolean runFlag = false;
	
	// Preferences
	public SharedPreferences prefs;
	public String USERNAME;
	public String PASSWORD;
	public int INTERVAL;
	public String SERVER;
	
	public LocationManager mlocManager;
	public LocationListener mlocListener;
	
	// Notifications
	public Notification notification;
	public boolean submission_notification = false;
	public NotificationManager mNotificationManager;

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}
	
	public void onCreate(){
		super.onCreate();
		
		prefs = PreferenceManager.getDefaultSharedPreferences(this);
        prefs.registerOnSharedPreferenceChangeListener(this);
        updatePreferences();
	}
	
	public int onStartCommand(Intent intent, int flags, int startId){
		super.onStartCommand(intent, flags, startId);
		mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        mlocListener = new MyLocationListener();
        mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 1000, 0, mlocListener);
		this.runFlag = true;
		return START_STICKY;
	}
	
	public void onDestroy(){
		super.onDestroy();
		mlocManager.removeUpdates(mlocListener);
		if(mNotificationManager != null){
			mNotificationManager.cancel(1);
		}
		this.runFlag = false;
	}
	
	public class MyLocationListener implements LocationListener {
		Date date;
	    
    	public void onLocationChanged(Location loc){
    		Log.i("SubmitterService", "Location changed.");
    		lat = loc.getLatitude();
    		lng = loc.getLongitude();
    		date = new Date();
    		if((date.getTime()/1000L) >= (last + INTERVAL) ){
    			Log.i("SubmitterService", "Starting submitter thread.");
    			last = date.getTime()/1000L;
    			stmp = String.valueOf(last);
    			new SubmitLocation().execute((Void[])null);
    		}
    		
    	}

    	public void onProviderDisabled(String provider){
    		Toast.makeText(getApplicationContext(), getString(R.string.msg_gpsdisabled), Toast.LENGTH_SHORT).show();
    	}

    	public void onProviderEnabled(String provider){
    		Toast.makeText( getApplicationContext(), getString(R.string.msg_gpsenabled), Toast.LENGTH_SHORT).show();
    	}

    	public void onStatusChanged(String provider, int status, Bundle extras){}

    }
    
	/**
	 * This class starts a new Thread which uses PointSubmitter to upload points.
	 *
	 */
    public class SubmitLocation extends AsyncTask <Void, Void, Void> {
    	private PointSubmitter httpRetriever = new PointSubmitter(USERNAME, PASSWORD);
    	private String response;
	    
		@Override
		protected Void doInBackground(Void... arg0) {
			submit(lat, lng, stmp);
			return null;
		}
	    
	    public boolean submit(double latitude, double longitude, String timestamp) {
	        Point p = new Point(latitude, longitude);
	        response = httpRetriever.retrieve(p);
	        last_response = response;
	        last_full_submission = new Date().getTime()/1000L;
	        
	        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
	        last_full_submission_string = formatter.format(new Date());
	        
	        // Create notification
	        try{
	        	updateSubmissionNotification(last_response, last_full_submission_string);
	        } catch(Exception e){
	        	
	        }

	        return true;
	        
	    }
	    
	    protected void onPostExecute(){

	    }
	    
	    protected void onProgressUpdate(Integer... progress) {
	    	//Toast.makeText( getApplicationContext(), "Progress: "+response, Toast.LENGTH_LONG).show();
	    }
    	
    }

	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
		updatePreferences();
	}
	
	/**
	 * Update username and password whenever they are changed.
	 */
	public void updatePreferences(){
		USERNAME = prefs.getString("username", "");
		PASSWORD = prefs.getString("password", "");
		SERVER = Properties.DEFAULT_SERVER;
		try{
			INTERVAL = prefs.getInt("frequency", 10);
		} catch (Exception e) {
			INTERVAL = 10;
		}
	}
	
	/**
	 * Display a notification when points are submitted.
	 * (Notification is passive and does not acquire.)
	 */
	public void createSubmissionNotification(){
    	final String ns = Context.NOTIFICATION_SERVICE;
    	mNotificationManager = (NotificationManager) getSystemService(ns);
    	int icon = android.R.drawable.ic_menu_mapmode;
    	CharSequence tickerText = "ENEOmobile is working.";
    	long when = System.currentTimeMillis();
    	notification = new Notification(icon, tickerText, when);
    	notification.flags |= Notification.FLAG_ONGOING_EVENT;
    	
    	submission_notification = true;
    }
	
	public void updateSubmissionNotification(String last_response, String last_full_submission_string){
		if(!submission_notification){
			createSubmissionNotification();
		}
		
		CharSequence contentText;
		
		if(last_response.equals("OK")){
			notification.icon = android.R.drawable.ic_menu_mapmode;
			notification.tickerText = null;
			contentText = getResources().getText(R.string.msg_lastsubmission) + ": "+last_full_submission_string+".";
		} else {
			notification.icon = android.R.drawable.stat_notify_error;
			notification.tickerText = getResources().getText(R.string.msg_wronglogin);
			contentText = getResources().getText(R.string.msg_checklogin);
		}
		
		Context context = getApplicationContext();
		CharSequence contentTitle = "ENEOmobile";
		
		Intent notificationIntent = new Intent(this, EneoActivity.class);
		PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
		
		notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
		mNotificationManager.notify(1, notification);
	}

}
